import { useEffect, useState } from 'react';
import { ethers } from 'ethers';

// Components
import Navigation from './components/Navigation';

// ABIs
import Token from './abis/Token.json'

import OcbcToken from './abis/OcbcToken.json'

// Config
import config from './config.json';
import { notification,Modal,Steps,Table,Input,Result } from "antd"

const Step = Steps.Step;

function App() {
  const [provider, setProvider] = useState(null)
  const [token, setToken] = useState(null)
  const [exRate, setExRate] = useState(0)
  const [account, setAccount] = useState(null)
  const [visible, setVisible] = useState(false)
  const [balance, setBalance] = useState(null)
  const [okText, setOkText] = useState("Next")
  const [current, setCurrent] = useState(0)
  const [inputAmount, setInputAmount] = useState('')
  const [fromToCurrency, setFromToCurrency] = useState('')
  const [inputAdd, setInputAdd] = useState('')
  const [showDetail, setShowDetail] = useState(true)
  const [showResult, setShowResult] = useState(false)
  const [data, setDatasource] = useState([{
    sender: 'system',
    recipient: 'system',
    amount: 1000,
    currency: 'SGD-SGD',
    date: '2024-1-1'
  }]);
  const [users, setUsers] = useState([{
    address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
    bank: 'OCBC Bank',
    currency: 'SGD',
    name: 'sun wen yang',
    balance: 1000
  }, {
    address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
    bank: 'OCBC Bank',
    currency: 'SGD',
    name: 'feng ji min',
    balance: 1000
  }, {
    address: '0x90F79bf6EB2c4f870365E785982E1f101E93b906',
    bank: 'OCBC Bank',
    currency: 'CHN',
    name: 'zou yi kang',
    balance: 1000
  }]);
  const [curUser, setCurUser] = useState(null);

  const loadEthersData = async () => {

    const provider = new ethers.providers.JsonRpcProvider(config.network);

    const network = await provider.getNetwork()

    const accounts = await provider.listAccounts()
    console.log(accounts[0])

    const wallet = new ethers.Wallet(config[network.chainId].walletPrivateKey, provider);

    const tokenAddress = config[network.chainId].ocbcToken.address;

    const tokenContract = new ethers.Contract(tokenAddress, OcbcToken, wallet);

    const supply = await tokenContract.totalSupply()
    console.log(supply.toString())

    let bal0 = await tokenContract.balanceOf(accounts[0])
    let bal2 = await tokenContract.balanceOf(accounts[2])
    console.log(accounts[0], bal0.toString())
    console.log(accounts[2], bal2.toString())

    const amount = ethers.utils.parseUnits("1", 1);
    const mt = await tokenContract.mint(accounts[0], amount)

    bal0 = await tokenContract.balanceOf(accounts[0])
    console.log('mint', accounts[0], bal0.toString())

    const tx = await tokenContract.transfer(accounts[2], amount);

    console.log('tx', tx)

    bal2 = await tokenContract.balanceOf(accounts[2])
    console.log('transfered', accounts[2], bal2.toString())


    setProvider(provider)
    setToken(tokenContract)

  }

  const loadBlockchainData = async () => {
    const { ethereum } = window;
    const provider = new ethers.providers.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const network = await provider.getNetwork()
    const token = new ethers.Contract(config[network.chainId].token.address, Token, signer)
    const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });

    setProvider(provider)
    setToken(token)

    // 监听事件，切换账号后，改变navigation栏的地址显示
    window.ethereum.on('accountsChanged', async () => {
      console.log('change event')
      const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
      const account = ethers.utils.getAddress(accounts[0])
      const balance = await token.balanceOf(account);
      setBalance(balance.toString());
      setAccount(account);

      users.map(item => {
        if (item.address === account) {
          setCurUser(item)
        }
      });
    })
  }

  useEffect(() => {
    loadBlockchainData()
    loadEthersData()
  }, [])


  var columns = [{
    title: 'sender',
    dataIndex: 'sender',
    render: function(text) {
      return <a href="javascript:;">{text}</a>;
    }
  }, {
    title: 'recipient',
    dataIndex: 'recipient'
  }, {
    title: 'amount',
    dataIndex: 'amount'
  }, {
    title: 'currency',
    dataIndex: 'currency'
  }, {
    title: 'date',
    dataIndex: 'date'
  }];

  const openNotificationWithIcon = type => {
    notification[type]({
      message: 'Param Illegal!',
      description:
        'This is the content of the notification. This is the content of the notification. This is the content of the notification.',
    });
  };

  function isNumber(value) {
    return !isNaN(parseFloat(value)) && isFinite(value);
  }

  const showModal = () => {
    if(inputAdd == "" || inputAmount == "" || !isNumber(inputAmount)){
      openNotificationWithIcon('warning')
    }
    else{
      setInputAmount(inputAmount);
      let ex = (Math.floor(Math.random() * 100) + 1)/ 100 + 5
      users.map(item => {
        if (item.address === inputAdd) {
          setFromToCurrency(Math.round((inputAmount * ex)*100)/100 + "  " + item.currency);
        }
      });
      if(curUser.currency == "SGD"){
        setExRate(ex)
      }
      if(curUser.currency == "CHN"){
        setExRate(ex / 5)
      }
      setInputAdd(inputAdd);
      const visible = true;
      setVisible(visible);
      setShowDetail(true);
      setShowResult(false);
    }
  }
  const handleOk = async (e) => {
    if(current === 0){
      setCurrent(1)
      setShowDetail(false);
    }
    if(current === 1){
      // Mint 
      const signer = await provider.getSigner()
      const add = await signer.getAddress()
      let transaction = await token.connect(signer).mintToken(add, inputAmount)
      await transaction.wait()
      let transfer = await token.connect(signer).transferFrom(add, inputAdd, inputAmount)
      await transfer.wait()
      const balance = await token.balanceOf(add);
      setBalance(balance.toString());
      curUser.balance = curUser.balance - inputAmount

      setCurUser(curUser)
      setCurrent(2)
      setShowResult(true);
      setOkText("Complete")

      var stamp= new Date().getTime() + 8 * 60 * 60 * 1000;
      var curDate = new Date(stamp).toISOString().replace(/T/, ' ').replace(/\..+/, '').substring(0, 19);
      

      users.map(item => {
        if (item.address === inputAdd) {
          let newObj = {
            sender: curUser.name,
            recipient: item.name,
            amount: inputAmount,
            currency: curUser.currency,
            date: curDate
          };
          let newArr = [...data, newObj];
          setDatasource(newArr);
        }
      });

    }
    if(current === 2){
      // Transfer
      const signer = await provider.getSigner()
      const add = await signer.getAddress()
      setCurrent(0)
      setOkText("Next")
      setVisible(false)
    }
  }
  const handleCancel = (e) => {
    setCurrent(0)
    setOkText("Next")
    setVisible(false)
  }
  const changeAdd = (event) => {
    const word = event.target.value
    setInputAdd(word)
  }
  const changeAmt = (event) => {
    const word = event.target.value
    setInputAmount(word)
  }
  return (
    <div className='background'>
      <Navigation token={token} account={account} setAccount={setAccount} users={users} setCurUser={setCurUser} balance={balance} setBalance={setBalance} />

      <div className='cards__section'>
        <h3>Services For You</h3>

        <hr />

            <div className='carda'>
              <h3> Account Details</h3>
              <div className='card__info_a'>
                <h5>addres:  </h5><br/>
                <h5>token balance: </h5> <br/>
                <h5>bank : </h5> <br/>
                <h5>account balance: </h5><br/>
                <h5>currency: </h5> 
              </div>
              <div className='card_account'>
                <p>{account}</p><br/>
                <p>{balance}</p><br/>
                <p>{curUser === null ? '' : curUser.bank}</p><br/>
                <p>{curUser === null ? '' : curUser.balance}</p><br/>
                <p>{curUser === null ? '' : curUser.currency}</p><br/>
              </div>
            </div>

            <div className='cardb'>
              <h3> Send Money</h3>
              <div className='card_input'>
                <h5>recipient addres:  </h5>
                  <Input onChange={changeAdd} placeholder="address"/><br/><br/>
                <h5>amount: </h5> 
                  <Input onKeyUp="value=value.replace(/[^\d^\.]+/g,'').replace('.','$#$').replace(/\./g,'').replace('$#$','.')" onChange={changeAmt} placeholder="amount" />
              </div>
              <button type="button" className='transfer' onClick={showModal}>tranfer by token </button>
              <Modal title="Transfer By Token" okText={okText} width={800} height={800} visible={visible} onOk={handleOk} onCancel={handleCancel}>
                  <br/><br/><br/>
                  <Steps current={current}>
                  <Step title="Confirm" description="Confirm information." />
                  <Step title="Transfer" description="Genetate transfer." />
                  <Step title="Complete" description="Transfer is successful." />
                  </Steps>
                    <div className='card__input' style={{ display: showDetail ? "inline-block" : "none" }}>
                      <h3>Transfer Details: </h3><br/>
                      <h5>Recipient Addres:</h5>
                      <h5>Send Amount: </h5>
                      <h5>Receive Amount: </h5>
                      <h5>Exchange Rate: </h5>
                    </div>
                    <div className='card__input1' style={{ display: showDetail ? "inline-block" : "none" }}>
                      <h3> </h3><br/>
                      <p>{inputAdd}</p>
                      <p>{inputAmount}</p>
                      <p>{fromToCurrency}</p>
                      <p>{exRate}</p>
                    </div>
                    <Result style={{ display: showResult ? "block" : "none" }} status="success" title="Successfully transfer to recipient!"/>
                    <br/><br/>
              </Modal>
            <div>
      </div>
            </div>
            <div className='cardc'>
              <h3> Account Movements</h3>
                <Table columns={columns} dataSource={data} pagination={{ pageSize: 5 }} />
            </div>
      </div>


    </div>
  );
}


export default App;
